module Utils where

import Data.Maybe

readInt     = (read :: String -> Int)
readInteger = (read :: String -> Integer)
readDouble  = (read :: String -> Double)

first :: (a -> c) -> (a, b) -> (c, b)
first f (x, y) = (f x, y)

second :: (b -> c) -> (a, b) -> (a, c)
second f (x, y) = (x, f y)

(&&&) :: (a -> b) -> (a -> c) -> a -> (b, c)
(&&&) f g x = (f x, g x)

(***) :: (a -> c) -> (b -> d) -> (a, b) -> (c, d)
(***) f g (x, y) = (f x, g y)

(!?) :: [a] -> Int -> Maybe a
[] !? n     = Nothing
(x:_) !? 0 = Just x
(_:xs) !? n = xs !? (n - 1)

groupn :: Int -> [a] -> [[a]]
groupn _ [] = []
groupn n xs = (take n xs) : (groupn n (drop n xs))

tok :: Eq a => [a] -> [a] -> [[a]]
tok _ [] = []
tok delims lst@(x:xs) = 
    if elem x delims then
        tok delims xs
    else
        token : tok delims rest
        where
            token = takeWhile (not . (`elem` delims)) lst
            rest = drop (length token) lst
        
repl :: Eq a => a -> a -> [a] -> [a]
repl old new = map (\x -> if x /= old then x else new)